#include <math.h>
#include "types.h"
#include "global.h"
#include "ms_reg.h"
#include "ms_rwreg.h"
#include "debug.h"
#include "Common.h"
#include "msosd.h"
#include "Board.h"
#include "menudef.h"
#include "msdlc.h"
#include "msace.h"
#if ENABLE_HDMI
#include "msHDMI.h"
#include "msHDMIACE.h"
#endif
#include "misc.h"
#include "drvosd.h"
#include "drvgpio.h"
#include "adjust.h"
#if ENABLE_LED_CONTROLLER
#include "LEDControl.h"
#endif
#if USE_DAC_ADJ
#include "drvDAC.H"
#endif
////////////////////////////////////////
//#include "drvAdjust.h"
//#include "halRwreg.h"
///////////////////////////////////////
#if ENABLE_DPS
#include "msdps_setting.h"
#endif

#include "drvDAC_U.h"
//===================================================
// Local function declaration
#if UsesRGB
void mStar_AdjustRedColor( BYTE rColor, BYTE gColor, BYTE bColor );
void mStar_AdjustGreenColor( BYTE rColor, BYTE gColor, BYTE bColor );
void mStar_AdjustBlueColor( BYTE rColor, BYTE gColor, BYTE bColor );
#else
void mStar_AdjustRedColor( BYTE color, BYTE contrast );
void mStar_AdjustGreenColor( BYTE color, BYTE contrast );
void mStar_AdjustBlueColor( BYTE color, BYTE contrast );
#endif

extern void GetColorTempRGB(ColorType *pstColor);
extern Bool IsColorspaceRGB(void);

void mStar_AdjustBlackLevel( BYTE BlackLevel );

#if ENABLE_LED_CONTROLLER && LED_CTRL_BRIGHTNESS_BY_CURRENT
#define RealMaxBrightnessValue  0xFF
#define RealMinBrightnessValue  0x00 // 25 120130 Max test
#define RealAbsoluteMinBrightnessValue  RealMinBrightnessValue
#else // !LED_CTRL_BRIGHTNESS_BY_CURRENT
#if(MainBoardType==MainBoard_3244_USB)
#define RealMaxBrightnessValue  0xFF
#define RealMinBrightnessValue  0x7F
#define RealAbsoluteMinBrightnessValue  0x30
#elif(MainBoardType==MainBoard_3598 || MainBoardType == MainBoard_4432)
#define RealMaxBrightnessValue                0xFF
#define RealMinBrightnessValue                30
#define RealAbsoluteMinBrightnessValue  0x00  //Rex 100712//0x03  2009-10-08 Brad==> 0x00
#elif(MainBoardType == MainBoard_4663)
#define RealMaxBrightnessValue                0xFF
#define RealMinBrightnessValue                30
#define RealAbsoluteMinBrightnessValue  0x00
#elif(MainBoardType==MainBoard_4534)
#define RealMaxBrightnessValue                0xFF
#define RealMinBrightnessValue                30
#define RealAbsoluteMinBrightnessValue  0x00
#elif(MainBoardType==MainBoard_3959)
#define RealMaxBrightnessValue              0xFF
#define RealMinBrightnessValue              30
#define RealAbsoluteMinBrightnessValue  0x00
#elif (MainBoardType==MainBoard_3661)
#define RealMaxBrightnessValue          0xFF
#define RealMinBrightnessValue          0x4D//ff-9c //0x66   //dcr=fc
#define RealAbsoluteMinBrightnessValue  0x15//0x13//0x03
#else
#define RealMaxBrightnessValue  0xFF
#define RealMinBrightnessValue  0x7F
#define RealAbsoluteMinBrightnessValue  0x30
#endif
#endif

#define LowBoundDCRRealBriRatio          30     // CCFL: 30%, LED:50%
#define RealMinDcrBrightnessValue    ((((RealMaxBrightnessValue - RealMinBrightnessValue) * LowBoundDCRRealBriRatio) / 100) + RealMinBrightnessValue)

//****************************************************
#define MaxBacklightNowValue    240  // HongYi suggest 100712 Rex
#define MinBacklightNowValue      20//17//29  //39  //19//17

#if MainBoardType==MainBoard_3598 || MainBoardType == MainBoard_4432 || MainBoardType == MainBoard_4663
#define AbsMostDarkest1  ((CURRENT_INPUT_IS_VGA())?(19):(17))  // 16  //20081201
#define AbsNearDarkest1  ((CURRENT_INPUT_IS_VGA())?(24):(20))  // 18
#define AbsMostDarkest2  ((CURRENT_INPUT_IS_VGA())?(19):(17))  // 17
#define AbsNearDarkest2  ((CURRENT_INPUT_IS_VGA())?(25):(22))  // 20
#else
#define AbsMostDarkest1  ((CURRENT_INPUT_IS_VGA())?(16):(16))  // 16  //20081201
#define AbsNearDarkest1  ((CURRENT_INPUT_IS_VGA())?(19):(17))  // 18
#define AbsMostDarkest2  ((CURRENT_INPUT_IS_VGA())?(16):(16))  // 17
#define AbsNearDarkest2  ((CURRENT_INPUT_IS_VGA())?(21):(19))  // 20
#endif
//****************************************************
BYTE code msAdjustNullData[] = {0};
void msAdjustDummy(void)
{
    BYTE xdata i = msAdjustNullData[0];
}
void mStar_AdjustDcrBrightness( void )
{
    static BYTE xdata brightness;
    static BYTE xdata DcrCutoffFlag = 0;    //DCR new rule 081128

#if ENABLE_DEBUG
static BYTE xdata PreValue;
#endif

    if( BacklightNow < MinBacklightNowValue )
        BacklightNow = MinBacklightNowValue;

    if( BacklightNow > MaxBacklightNowValue )
    {
        brightness = RealMaxBrightnessValue;
        DcrCutoffFlag = 0;    //20081201
    }
    else if( BacklightNow <= MinBacklightNowValue )
    {
        if( SetDarkestFlag ) // the black pattern
        {
            SetDarkestFlag = 0;
            PreBrightData = 0; // to make sure if bright data exist, it will update brightness.
            //brightness = RealAbsoluteMinBrightnessValue;  // set logical absolute dark value, // RealMinBrightnessValue;
            if( DcrCutoffFlag == 0 ) // DcrCutoffFlag nitial value is 0
            {
                if(( DarkData <= AbsMostDarkest1 ) && ( BrightData <= AbsNearDarkest1 ) )   // >>>  logical absolute dark condition  <<< 20081128
                    // set logical absolute dark value, // RealMinBrightnessValue;
                {
                    //brightness = RealMinDcrBrightnessValue;  // set logical absolute dark value, // RealMinBrightnessValue;
                    DcrCutoffFlag = 1;
                }
                brightness = RealMinDcrBrightnessValue;  // set logical absolute dark value, // RealMinBrightnessValue;
            }
            else
            {
                if(( DarkData <= AbsMostDarkest2 ) && ( BrightData <= AbsNearDarkest2 ) )   // set logical absolute dark value,
                {
                    if( brightness > RealAbsoluteMinBrightnessValue )
                        brightness--;  // set logical absolute dark value, // RealMinBrightnessValue;
#if defined(DCRClearBacklight)
                     if(OSD_MENU_EXIST() && ( brightness < RealMinBrightnessValue ) )
                        brightness = RealMinBrightnessValue;
                     ForceDelay1ms( 100 );
#endif
                }
                else
                {
                    DcrCutoffFlag = 0;
                    brightness = RealMinDcrBrightnessValue;
                }
            }
        }    // if(SetDarkestFlag)
        else // RealMinDcrBrightnessValue=98 -> brightness >=98 (min)
        {
            DcrCutoffFlag = 0;
            brightness = RealMinDcrBrightnessValue;
        }
    }
    else  // RealMinDcrBrightnessValue=98 -> brightness >=98 (min)
    {
        DcrCutoffFlag = 0;
        brightness = ((( DWORD )( BacklightNow - MinBacklightNowValue ) * ( RealMaxBrightnessValue - RealMinDcrBrightnessValue ) ) / ( MaxBacklightNowValue - MinBacklightNowValue ) ) + RealMinDcrBrightnessValue;
    }

    #if 0//DEBUG_PRINT_ENABLE
    printData( "---BacklightNow =%d", BacklightNow );
    printData( "---brightness =%d", brightness );
    #endif

    #if ENABLE_DEBUG
    if(abs(PreValue-BacklightNow) > 3)
    {
        PreValue = BacklightNow;
    printData( "---BacklightNow =%d", BacklightNow );
    }
    #endif

#if ENABLE_LED_CONTROLLER
    msLED_DimmingPWMAdjust(brightness);
    drvGPIO_SetBacklightDuty(0,0); // wait for coding, prevent complier warning
#else
    #if BRIGHTNESS_INVERSE  //+Duty power
    drvGPIO_SetBacklightDuty(BrightnessPWM, 0xFF-brightness);
    #else                           //-Duty power
    drvGPIO_SetBacklightDuty(BrightnessPWM, brightness);
    #endif
#endif

    #if defined(DCRClearBacklight)
    if( brightness == RealAbsoluteMinBrightnessValue )
    {

        if( BackLightActiveFlag )
            hw_ClrBlacklit();
    }
    else
    {
        if( !BackLightActiveFlag )
            hw_SetBlacklit();
    }
    #endif
}

void mStar_AdjustBrightness( BYTE brightness )
{
    brightness = ((( DWORD )brightness * ( RealMaxBrightnessValue - RealMinBrightnessValue ) ) / 100 ) + RealMinBrightnessValue;

    BacklightNow = BacklightPrev = brightness;

#if ENABLE_LED_CONTROLLER
    msLED_DimmingPWMAdjust(brightness);
#else
    #if BRIGHTNESS_INVERSE  //+Duty power
    drvGPIO_SetBacklightDuty(BrightnessPWM, 0xFF-brightness);
    //drvGPIO_SetBacklightDuty(BrightnessPWM, 0);
    #else                           //-Duty power
    drvGPIO_SetBacklightDuty(BrightnessPWM, brightness);
    //drvGPIO_SetBacklightDuty(BrightnessPWM, 0xff);
    #endif
#endif
}
//=================================================================================
//volume=((DWORD)volume*63)/100+57;    //LM929 2W for Lai
//volume=((DWORD)volume*84)/100+93;    //LM929 3W && Carrefour for Lai
//volume=((DWORD)volume*92)/100+93;    //-0923-LM929 3W && Carrefour for Lai
//volume=((DWORD)volume*170)/100+57;   //LM729 && Carrefour for Lu
//volume = ( ( DWORD ) volume * 70) / 20 +90; //qx.long20061213
//volume = ( ( DWORD ) volume * 34) / 100 +160; //qx.long20061213
// volume=((DWORD)volume*146)/100+51;   //1127 for Lai TESTING 19" AUDIO
//=================================================================================
#if AudioFunc
#if (MainBoardType==MainBoard_3893)
#if VOLUME_INVERSE
#define MinVolumeValue      (0xFF-0xFF)
#define MaxVolumeValue      (0xFF-0)
#else
#define MinVolumeValue      (0x00)
#define MaxVolumeValue      (0xFF)
#endif
#elif (MainBoardType==MainBoard_3661)
#define MinVolumeValue      20//0
#define MaxVolumeValue      246
#elif (MainBoardType==MainBoard_3598 || MainBoardType == MainBoard_4432)
#if ModelName==OTS_UU215DGLW
#define MinVolumeValue      60
#define MaxVolumeValue      255
#else
#define MinVolumeValue      20
#define MaxVolumeValue      255
#endif
#elif (MainBoardType==MainBoard_3834)  // 100809
#define MinVolumeValue      0//60
#define MaxVolumeValue      184//255
#elif (MainBoardType==MainBoard_4534)
#define MinVolumeValue      20
#define MaxVolumeValue      255
#elif (MainBoardType==MainBoard_3959)  // 100809
#define MinVolumeValue      0//20
#define MaxVolumeValue      255
#elif (MainBoardType==MainBoard_3836)
#define MinVolumeValue      0
#define MaxVolumeValue      255
#elif (MainBoardType==MainBoard_4266)  // Rex 100705
#define MinVolumeValue      0
#define MaxVolumeValue      255
#elif (MainBoardType==MainBoard_3834_M02)   // Annie 2011.10.24
#define MinVolumeValue      0
#define MaxVolumeValue      255
#else
#define MinVolumeValue      160
#define MaxVolumeValue      255
#endif

#define Volume50Value           ((MaxVolumeValue-MinVolumeValue)*70/100+MinVolumeValue)
#if AdjustVolume_UseTable
#if USE_DAC_ADJ
BYTE code VolumeValueTable[]=
{
0x00,0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x08,
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11, //10
0x12,0x12,0x12,0x13,0x14,0x15,0x16,0x17,0x17,0x18, //20
0x18,0x18,0x19,0x19,0x19,0x1A,0x1A,0x1A,0x1A,0x1B,//30
0x1B,0x1B,0x1C,0x1C,0x1C,0x1D,0x1D,0x1E,0x1F,0x20,//40
0x20,0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,//50
0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2C,//60
0x2D,0x2D,0x2E,0x2E,0x2F,0x30,0x31,0x31,0x32,0x33,//70
0x33,0x34,0x34,0x35,0x35,0x36,0x37,0x38,0x38,0x39,//80
0x3A,0x3B,0x3B,0x3C,0x3C,0x3D,0x3D,0x3E,0x3E,0x3F,//90
0x3F,//100                                                                          //0xEE
};


#else
BYTE code VolumeValueTable[]=
{
0x00,0x20,0x23,0x24,0x26,0x27,0x29,0x2A,0x2C,0x2D,
0x30,0x32,0x35,0x38,0x3B,0x3E,0x41,0x44,0x47,0x4A, //10
0x4C,0x50,0x55,0x59,0x5E,0x62,0x67,0x6C,0x70,0x75, //20
0x79,0x7C,0x7F,0x81,0x84,0x86,0x89,0x8B,0x8E,0x90,//30
0x94,0x97,0x9A,0x9D,0xA0,0xA3,0xA6,0xA9,0xAB,0xAD,//40
0xB0,0xB1,0xB3,0xB4,0xB6,0xB7,0xB9,0xBA,0xBC,0xBE,//50
0xC0,0xC1,0xC3,0xC4,0xC6,0xC7,0xC9,0xCA,0xCC,0xCE,//60
0xD0,0xD1,0xD3,0xD4,0xD5,0xD7,0xD9,0xDA,0xDC,0xDE,//70
0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,//80
0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,//90
0xEE,//100                                                                          //0xEE
};
#endif
#endif
int code new_VolumeValueTable[11]=
{
#if 0
	-448,	/*mute   volume <--> 0*/
	-404,	/*normal volume <--> 10*/
	-360,	/*normal volume <--> 20*/
	-324,	/*normal volume <--> 30*/
	-280,	/*normal volume <--> 40*/
	-236,	/*normal volume <--> 50*/
	-190,		/*normal volume <--> 60*/
	-140,		/*normal volume <--> 70*/
	-100,		/*normal volume <--> 80*/
	-55,		/*normal volume <--> 90*/
	-10		/*normal volume <--> 100*/
#else
	-448,	/*mute   volume <--> 0*/
	-124,	/*normal volume <--> 10*/
	-114,	/*normal volume <--> 20*/
	-104,	/*normal volume <--> 30*/
	-94,	/*normal volume <--> 40*/
	-84,	/*normal volume <--> 50*/
	-74,	/*normal volume <--> 60*/
	-64,	/*normal volume <--> 70*/
	-54,	/*normal volume <--> 80*/
	-44,	/*normal volume <--> 90*/
	-34		/*normal volume <--> 100*/
#endif
};

void mStar_AdjustVolume( BYTE volume )
{
#if 0
    if( MinVolume >= volume )
        volume = 0;
     if(volume==0)      //111031 add for meet the volume adjustment flow
    {
        hw_SetMute();
        Delay1ms(2);
     }
    if( volume )
    {
       // hw_ClrMute();

        //volume=TestByte;
        #if AdjustVolume_UseTable
         volume=VolumeValueTable[volume];
        #else
        if( volume >= 50 )
            volume = (( DWORD )volume * ( MaxVolumeValue - Volume50Value ) ) / 50 + 2 * Volume50Value - MaxVolumeValue;
        else
            volume = (( DWORD )volume * ( Volume50Value - MinVolumeValue ) ) / 50 + MinVolumeValue;
        #endif
    }
    else
    {
       // hw_SetMute();
        volume = 0;
    }

#if USE_DAC_ADJ
    msAudioLineOutGain(volume);

    if(volume!=0)
        drvGPIO_SetBacklightDuty(VolumePWM,AMPDBVALUE);
    else
        drvGPIO_SetBacklightDuty(VolumePWM,0);

#else

#if VOLUME_INVERSE  //+Duty power
        drvGPIO_SetBacklightDuty(VolumePWM, 0xFF-volume);
#else                           //-Duty power
        drvGPIO_SetBacklightDuty(VolumePWM, volume);
#endif

#endif
    if (volume!=0)
    {
        hw_ClrMute();
    }
#else
	if( MinVolume >= volume )
        volume = 0;
	printData("mStar_AdjustVolume volume = %d",volume);
    if(volume==0)      //111031 add for meet the volume adjustment flow
    {
        msAudioDPGA_Mute();
    }
    else
    {
		msAudioDPGA_SetVolume(E_AUDIO_LEFT_RIGHT_CH,new_VolumeValueTable[volume/10]);
	}
#endif
}
#endif

void mStar_AdjustRGBColor(BYTE u8Contrast, BYTE u8Red, BYTE u8Green, BYTE u8Blue)
{
    if(IsColorspaceRGB()
#if ENABLE_DISPLAY_UNDERSCAN||CHIP_ID == CHIP_TSUMD
        && !g_SetupPathInfo.bMRWR2Y
#endif
        && (UserPrefInputColorFormat == INPUTCOLOR_RGB) //20150121
        )
    {
#if (CHIP_ID == CHIP_TSUMC)||(CHIP_ID == CHIP_TSUMD)||(CHIP_ID == CHIP_TSUM9)||(CHIP_ID == CHIP_TSUMF)
        msWriteByteMask(SC0_02, 0, _BIT3);
#endif
        msAdjustPCContrastRGB(MAIN_WINDOW, u8Contrast, u8Red, u8Green, u8Blue);
    }
    else
    {
#if (CHIP_ID == CHIP_TSUMC)||(CHIP_ID == CHIP_TSUMD)||(CHIP_ID == CHIP_TSUM9)||(CHIP_ID == CHIP_TSUMF)
        msWriteByteMask(SC0_02, _BIT3, _BIT3);
#endif
        msAdjustVideoContrastRGB(MAIN_WINDOW,u8Contrast, u8Red, u8Green, u8Blue);
        //printMsg("\r\n YUV");
    }
}

void mStar_AdjustContrast( BYTE contrast )
{
    xdata ColorType CT;

    GetColorTempRGB(&CT);
    mStar_AdjustRGBColor(contrast, CT.u8Red, CT.u8Green, CT.u8Blue);
}

void mStar_AdjustRedColor( BYTE color, BYTE contrast )
{
    xdata ColorType CT;

    GetColorTempRGB(&CT);
    mStar_AdjustRGBColor(contrast, color, CT.u8Green, CT.u8Blue);
}
void mStar_AdjustGreenColor( BYTE color, BYTE contrast )
{
    xdata ColorType CT;

    GetColorTempRGB(&CT);
    mStar_AdjustRGBColor(contrast, CT.u8Red, color, CT.u8Blue);
}
void mStar_AdjustBlueColor( BYTE color, BYTE contrast )
{
    xdata ColorType CT;

    GetColorTempRGB(&CT);
    mStar_AdjustRGBColor(contrast, CT.u8Red, CT.u8Green, color);
}

void mStar_AdjustHPosition( WORD position )
{
    SC0_SET_IMAGE_START_H(position);//msWrite2Byte(SC0_07, position);
}

void mStar_AdjustVPosition( WORD position )
{
#if 1
#if DECREASE_V_SCALING
    position = (position>VSTART_OFFSET)?(position-VSTART_OFFSET):(0);
#endif
    SC0_SET_IMAGE_START_V(position);//msWrite2Byte( SC0_05, position );
#else
    if( DecVScaleFlag )
    {
        if( position <= ( VScaleDecValue / 2 ) )
            position = VScaleDecValue / 2 + 1;
        msWrite2Byte( SC0_05, position - ( VScaleDecValue / 2 ) );
    }
    else
    {
        if( position == 0 )
            position = 1;
        msWrite2Byte( SC0_05, position );
    }
#endif
	#if CHIP_ID==CHIP_TSUMD
    if((g_SetupPathInfo.bFBMode)&& msRead2Byte(REG_3818)&BIT3)
		mStar_SetIVS();
	#endif

}

// 100702 coding, modify to wait complete blanking
void mStar_WaitForDataBlanking( void )
{
    WORD retry = 0xffff;

    if( SyncLossState() || !bPanelOnFlag )
        return;

    while( retry-- && ( msReadByte(SC0_90)&BIT7 ) && !InputTimingChangeFlag );

    retry = 0xffff;

    while( retry-- && !( msReadByte(SC0_90)&BIT7 ) && !InputTimingChangeFlag );
}

void mStar_AdjustBackgoundColor( BYTE pattern )
{
    BYTE rColor = 0;
    BYTE gColor = 0;
    BYTE bColor = 0;
    if( pattern == 0 )
    {
        rColor = 0xFF;
    }
    else if( pattern == 1 )
    {
        gColor = 0xFF;
    }
    else if( pattern == 2 )
    {
        bColor = 0xFF;
    }
    else if( pattern == 4 )
    {
        rColor = 0xFF;
        gColor = 0xFF;
        bColor = 0xFF;
    }
    mStar_WaitForDataBlanking();
    drvOSD_FrameColorRGB(rColor, gColor, bColor);
}
